#pragma once 

#include<iostream>

#include<assert.h>


using namespace std;

namespace MyList{ 
  
//对单个节点进行封装
  template<class T>
  struct list_node{
  typedef list_node<T>node;

    list_node(const T& x = T())
    :val(x)
    {
      _prev = _next = nullptr;
    }
    T val;
    node* _prev;
    node* _next;
  };


//对迭代器进行封装 
    template<class T,class Ref,class Ptr>
      struct __list_iterator{
        typedef __list_iterator<T,Ref,Ptr> self;
        typedef list_node<T> node;
        
        __list_iterator(node* p)
          :_node(p){}


        self& operator++(){//迭代器自增所返回类型一样是迭代器
          _node = _node->_next;
          return *this;
        }

        self& operator--(){                  
          _node = _node->_prev;
          return *this;
        }

        self operator++(int){//迭代器自增所返回类型一样是迭代器
          self tmp(_node);
          _node = _node->_next;
          return tmp;
        }

        self operator--(int){                  
          self tmp(_node);
          _node = _node->_prev;
          return tmp;
        }

        Ref operator*(){
          return _node->val;
        }

        Ptr operator->(){
          return &_node->val;
        }

        bool operator!=(const self& x)const{
          return _node!=x._node;
        }

        bool operator==(const self& x)const{
          return _node==x._node;
        }
        node* _node;
      };



#include"Iterator.hpp"
//封装整体的链表
  template<class T>
    class list{
      public:
        typedef list_node<T> node;
        typedef __list_iterator<T,T&,T*> iterator;
        typedef __list_iterator<T,const T&,const T*> const_iterator;

        typedef MyList::ReverseIterator<iterator,T&,T*> reverse_iterator;
        typedef MyList::ReverseIterator<const_iterator,const T&,const T*> const_reverse_iterator;
        
        void empty_init(){
          _head = new node;
          _head->_next = _head->_prev = _head;
        }

        list()
        {
          empty_init();
        }

        void push_back(const T& x)
        {
         /* node* newnode = new node(x);
          node* prev = _head->_prev;

          prev->_next = newnode;
          newnode->_next = _head;

          newnode->_prev = prev;
          _head->_prev = newnode;*/

          insert(_head,x);
        }

        void push_front(const T& x){
          insert(begin(),x);
        }

        iterator insert(iterator pos , const T& x){
          node* cur = pos._node;
          node* newnode = new node(x);
          node* prev = cur->_prev;

          prev->_next = newnode;
          newnode->_prev = prev;

          cur->_prev = newnode;
          newnode->_next = cur;

          _size++;
          return newnode;//返回值为迭代器，这里返回node*以该指针来构造迭代器进行返回；
        }

        iterator erase(iterator pos){
          assert(pos._node!=_head);

          node* prev = pos._node->_prev;
          node* next = pos._node->_next;


          prev->_next = next;
          next->_prev = prev;

          --_size;
          return next;
        }

        void pop_back(){
          erase(_head->_prev);
        }

        void pop_front(){
          erase(begin());
        }

        iterator begin(){
          return iterator(_head->_next);
        }

        iterator end(){
          return iterator(_head);
        }

        const_iterator begin()const{
          return iterator(_head->_next);
        }

        const_iterator end()const{
          return iterator(_head);
        }

        reverse_iterator rbegin(){
          return iterator(end());
        }

        reverse_iterator rend(){
          return iterator(begin());
        }

        const_reverse_iterator rbegin()const{
          return iterator(end());
        }

        const_reverse_iterator rend()const{
          return iterator(begin());
        }
      private:
        node* _head;
        size_t _size;
    };


}
